const LETTER_TO_REGIONAL_INDICATOR_EMOJI: Record<string, string> = {
    A: '🇦',
    B: '🇧',
    C: '🇨',
    D: '🇩',
    E: '🇪',
    F: '🇫',
    G: '🇬',
    H: '🇭',
    I: '🇮',
    J: '🇯',
    K: '🇰',
    L: '🇱',
    M: '🇲',
    N: '🇳',
    O: '🇴',
    P: '🇵',
    Q: '🇶',
    R: '🇷',
    S: '🇸',
    T: '🇹',
    U: '🇺',
    V: '🇻',
    W: '🇼',
    X: '🇽',
    Y: '🇾',
    Z: '🇿',
}

/**
 * Returns country flag emoji for a given ISO 3166-1 alpha-2 country code.
 *
 * This is super simple because a country flag is in fact just the country's ISO code in _regional indicator_ form.
 * See: https://en.wikipedia.org/wiki/Regional_indicator_symbol
 */
export function countryCodeToFlag(countryCode: string): string {
    if (!countryCode || !countryCode.length || countryCode.length !== 2) {
        return ''
    }

    return `${LETTER_TO_REGIONAL_INDICATOR_EMOJI[countryCode[0]]}${LETTER_TO_REGIONAL_INDICATOR_EMOJI[countryCode[1]]}`
}

/**
 * Returns country flag emoji for a given ISO 639 language code.
 * This isn't needed often because the locales usually come in the nl-NL format (for dutch, for example)
 * but there are cases where we only see the first part in case the language isn't shared by more than
 * one country - such as the Netherlands.
 *
 * For most cases we can simply uppercase the language and that's the country code,
 * but there are some exceptions listed inside `LANGUAGE_CODE_TO_EMOJI_FLAG_OVERRIDE`
 */
export function languageCodeToFlag(languageCode: string): string {
    return LANGUAGE_CODE_TO_EMOJI_FLAG_OVERRIDE[languageCode] ?? countryCodeToFlag(languageCode.toLocaleUpperCase())
}

/**
 * This mapping is based on ISO 3166-1 Alpha-2.
 * See: https://www.iso.org/iso-3166-country-codes.html
 */
export const COUNTRY_CODE_TO_LONG_NAME: Record<string, string> = {
    AD: 'Andorra',
    AE: 'United Arab Emirates',
    AF: 'Afghanistan',
    AG: 'Antigua and Barbuda',
    AI: 'Anguilla',
    AL: 'Albania',
    AM: 'Armenia',
    AO: 'Angola',
    AQ: 'Antarctica',
    AR: 'Argentina',
    AS: 'American Samoa',
    AT: 'Austria',
    AU: 'Australia',
    AW: 'Aruba',
    AX: 'Åland Islands',
    AZ: 'Azerbaijan',
    BA: 'Bosnia and Herzegovina',
    BB: 'Barbados',
    BD: 'Bangladesh',
    BE: 'Belgium',
    BF: 'Burkina Faso',
    BG: 'Bulgaria',
    BH: 'Bahrain',
    BI: 'Burundi',
    BJ: 'Benin',
    BL: 'Saint Barthélemy',
    BM: 'Bermuda',
    BN: 'Brunei',
    BO: 'Bolivia',
    BQ: 'Bonaire, Sint Eustatius and Saba',
    BR: 'Brazil',
    BS: 'Bahamas',
    BT: 'Bhutan',
    BV: 'Bouvet Island',
    BW: 'Botswana',
    BY: 'Belarus',
    BZ: 'Belize',
    CA: 'Canada',
    CC: 'Cocos (Keeling) Islands',
    CD: 'Democratic Republic of the Congo', // Defined in the ISO as "Congo (the Democratic Republic of the)", simplified by us
    CF: 'Central African Republic',
    CG: 'Congo',
    CH: 'Switzerland',
    CI: "Côte d'Ivoire",
    CK: 'Cook Islands',
    CL: 'Chile',
    CM: 'Cameroon',
    CN: 'China',
    CO: 'Colombia',
    CR: 'Costa Rica',
    CU: 'Cuba',
    CV: 'Cabo Verde',
    CW: 'Curaçao',
    CX: 'Christmas Island',
    CY: 'Cyprus',
    CZ: 'Czechia', // More widely known in English as "Czech Republic", but ISO/UN/US Gov use "Czechia"
    DE: 'Germany',
    DJ: 'Djibouti',
    DK: 'Denmark',
    DM: 'Dominica',
    DO: 'Dominican Republic',
    DZ: 'Algeria',
    EC: 'Ecuador',
    EE: 'Estonia',
    EG: 'Egypt',
    EH: 'Western Sahara',
    ER: 'Eritrea',
    ES: 'Spain',
    ET: 'Ethiopia',
    FI: 'Finland',
    FJ: 'Fiji',
    FK: 'Falkland Islands (Malvinas)', // Although controversial, all of ISO/UN/US Gov use "Falkland Islands (Malvinas)"
    FM: 'Micronesia',
    FO: 'Faroe Islands',
    FR: 'France',
    GA: 'Gabon',
    GB: 'United Kingdom', // ISO defines as "United Kingdom of Great Britain and Northern Ireland" but we'll opt for the more common "United Kingdom"
    GD: 'Grenada',
    GE: 'Georgia',
    GF: 'French Guiana',
    GG: 'Guernsey',
    GH: 'Ghana',
    GI: 'Gibraltar',
    GL: 'Greenland',
    GM: 'Gambia',
    GN: 'Guinea',
    GP: 'Guadeloupe',
    GQ: 'Equatorial Guinea',
    GR: 'Greece',
    GS: 'South Georgia and the South Sandwich Islands',
    GT: 'Guatemala',
    GU: 'Guam',
    GW: 'Guinea-Bissau',
    GY: 'Guyana',
    HK: 'Hong Kong',
    HM: 'Heard Island and McDonald Islands',
    HN: 'Honduras',
    HR: 'Croatia',
    HT: 'Haiti',
    HU: 'Hungary',
    ID: 'Indonesia',
    IE: 'Ireland',
    IL: 'Israel',
    IM: 'Isle of Man',
    IN: 'India',
    IO: 'British Indian Ocean Territory',
    IQ: 'Iraq',
    IR: 'Iran',
    IS: 'Iceland',
    IT: 'Italy',
    JE: 'Jersey',
    JM: 'Jamaica',
    JO: 'Jordan',
    JP: 'Japan',
    KE: 'Kenya',
    KG: 'Kyrgyzstan',
    KH: 'Cambodia',
    KI: 'Kiribati',
    KM: 'Comoros',
    KN: 'Saint Kitts and Nevis',
    KP: 'North Korea', // ISO defines as "Korea (the Democratic People's Republic of)", simplified for common use by us
    KR: 'South Korea', // ISO defines as "Korea (the Republic of)", simplified for common use by us
    KW: 'Kuwait',
    KY: 'Cayman Islands',
    KZ: 'Kazakhstan',
    LA: 'Laos', // ISO defines as "Lao People's Democratic Republic", simplified for common use by us
    LB: 'Lebanon',
    LC: 'Saint Lucia',
    LI: 'Liechtenstein',
    LK: 'Sri Lanka',
    LR: 'Liberia',
    LS: 'Lesotho',
    LT: 'Lithuania',
    LU: 'Luxembourg',
    LV: 'Latvia',
    LY: 'Libya',
    MA: 'Morocco',
    MC: 'Monaco',
    MD: 'Moldova',
    ME: 'Montenegro',
    MF: 'Saint Martin',
    MG: 'Madagascar',
    MH: 'Marshall Islands',
    MK: 'North Macedonia',
    ML: 'Mali',
    MM: 'Myanmar',
    MN: 'Mongolia',
    MO: 'Macao',
    MP: 'Northern Mariana Islands',
    MQ: 'Martinique',
    MR: 'Mauritania',
    MS: 'Montserrat',
    MT: 'Malta',
    MU: 'Mauritius',
    MV: 'Maldives',
    MW: 'Malawi',
    MX: 'Mexico',
    MY: 'Malaysia',
    MZ: 'Mozambique',
    NA: 'Namibia',
    NC: 'New Caledonia',
    NE: 'Niger',
    NF: 'Norfolk Island',
    NG: 'Nigeria',
    NI: 'Nicaragua',
    NL: 'Netherlands',
    NO: 'Norway',
    NP: 'Nepal',
    NR: 'Nauru',
    NU: 'Niue',
    NZ: 'New Zealand',
    OM: 'Oman',
    PA: 'Panama',
    PE: 'Peru',
    PF: 'French Polynesia',
    PG: 'Papua New Guinea',
    PH: 'Philippines',
    PK: 'Pakistan',
    PL: 'Poland',
    PM: 'Saint Pierre and Miquelon',
    PN: 'Pitcairn',
    PR: 'Puerto Rico',
    PS: 'Palestine', // ISO defines as "Palestine, State of", simplified for common use by us
    PT: 'Portugal',
    PW: 'Palau',
    PY: 'Paraguay',
    QA: 'Qatar',
    RE: 'Réunion',
    RO: 'Romania',
    RS: 'Serbia',
    RU: 'Russia', // ISO defines as "Russian Federation", simplified for common use by us
    RW: 'Rwanda',
    SA: 'Saudi Arabia',
    SB: 'Solomon Islands',
    SC: 'Seychelles',
    SD: 'Sudan',
    SE: 'Sweden',
    SG: 'Singapore',
    SH: 'Saint Helena, Ascension and Tristan da Cunha',
    SI: 'Slovenia',
    SJ: 'Svalbard and Jan Mayen',
    SK: 'Slovakia',
    SL: 'Sierra Leone',
    SM: 'San Marino',
    SN: 'Senegal',
    SO: 'Somalia',
    SR: 'Suriname',
    SS: 'South Sudan',
    ST: 'Sao Tome and Principe',
    SV: 'El Salvador',
    SX: 'Sint Maarten',
    SY: 'Syria', // ISO defines as "Syrian Arab Republic", simplified for common use by us
    SZ: 'Eswatini',
    TC: 'Turks and Caicos Islands',
    TD: 'Chad',
    TF: 'French Southern Territories',
    TG: 'Togo',
    TH: 'Thailand',
    TJ: 'Tajikistan',
    TK: 'Tokelau',
    TL: 'Timor-Leste', // More widely known in English as "East Timor", but ISO/UN/US Gov use "Timor-Leste"
    TM: 'Turkmenistan',
    TN: 'Tunisia',
    TO: 'Tonga',
    TR: 'Türkiye', // More widely known in English as "Turkey", but ISO/UN/US Gov use "Türkiye"
    TT: 'Trinidad and Tobago',
    TV: 'Tuvalu',
    TW: 'Taiwan',
    TZ: 'Tanzania', // ISO defines as "Tanzania, the United Republic of", simplified for common use by us
    UA: 'Ukraine',
    UG: 'Uganda',
    UM: 'United States Minor Outlying Islands',
    US: 'United States', // ISO defines as "United States of America (the)", simplified for common use by us
    UY: 'Uruguay',
    UZ: 'Uzbekistan',
    VA: 'Vatican', // ISO defines as "Holy See (the)", simplified for common use by us
    VC: 'Saint Vincent and the Grenadines',
    VE: 'Venezuela',
    VG: 'British Virgin Islands',
    VI: 'U.S. Virgin Islands',
    VN: 'Viet Nam', // More widely known in English as "Vietnam", but ISO/UN/US Gov use "Viet Nam"
    VU: 'Vanuatu',
    WF: 'Wallis and Futuna',
    WS: 'Samoa',
    YE: 'Yemen',
    YT: 'Mayotte',
    ZA: 'South Africa',
    ZM: 'Zambia',
    ZW: 'Zimbabwe',

    // Not included in ISO 3166-1 Alpha-2, but we'll add them here for completeness
    XK: 'Kosovo',
}

export const LANGUAGE_CODE_TO_NAME: Record<string, string> = {
    // Base ones came from https://en.wikipedia.org/wiki/List_of_ISO_639_language_codes
    // Code used to generate the list: Object.fromEntries([...window.Table[1].children[1].children].map(row => [row.children[1].textContent, row.children[0].textContent]))
    ab: 'Abkhazian',
    aa: 'Afar',
    af: 'Afrikaans',
    ak: 'Akan',
    sq: 'Albanian',
    am: 'Amharic',
    ar: 'Arabic',
    an: 'Aragonese',
    hy: 'Armenian',
    as: 'Assamese',
    av: 'Avaric',
    ae: 'Avestan',
    ay: 'Aymara',
    az: 'Azerbaijani',
    bm: 'Bambara',
    ba: 'Bashkir',
    eu: 'Basque',
    be: 'Belarusian',
    bn: 'Bengali',
    bi: 'Bislama',
    bs: 'Bosnian',
    br: 'Breton',
    bg: 'Bulgarian',
    my: 'Burmese',
    ca: 'Catalan',
    ch: 'Chamorro',
    ce: 'Chechen',
    ny: 'Chichewa',
    zh: 'Chinese',
    cu: 'Church Slavonic',
    cv: 'Chuvash',
    kw: 'Cornish',
    co: 'Corsican',
    cr: 'Cree',
    hr: 'Croatian',
    cs: 'Czech',
    da: 'Danish',
    dv: 'Divehi',
    nl: 'Dutch',
    dz: 'Dzongkha',
    en: 'English',
    eo: 'Esperanto',
    et: 'Estonian',
    ee: 'Ewe',
    fo: 'Faroese',
    fj: 'Fijian',
    fi: 'Finnish',
    fr: 'French',
    fy: 'Western Frisian',
    ff: 'Fulah',
    gd: 'Gaelic',
    gl: 'Galician',
    lg: 'Ganda',
    ka: 'Georgian',
    de: 'German',
    el: 'Greek',
    kl: 'Kalaallisut',
    gn: 'Guarani',
    gu: 'Gujarati',
    ht: 'Haitian',
    ha: 'Hausa',
    he: 'Hebrew',
    hz: 'Herero',
    hi: 'Hindi',
    ho: 'Hiri Motu',
    hu: 'Hungarian',
    is: 'Icelandic',
    io: 'Ido',
    ig: 'Igbo',
    id: 'Indonesian',
    ia: 'Interlingua',
    ie: 'Interlingue',
    iu: 'Inuktitut',
    ik: 'Inupiaq',
    ga: 'Irish',
    it: 'Italian',
    ja: 'Japanese',
    jv: 'Javanese',
    kn: 'Kannada',
    kr: 'Kanuri',
    ks: 'Kashmiri',
    kk: 'Kazakh',
    km: 'Central Khmer',
    ki: 'Kikuyu',
    rw: 'Kinyarwanda',
    ky: 'Kirghiz',
    kv: 'Komi',
    kg: 'Kongo',
    ko: 'Korean',
    kj: 'Kuanyama',
    ku: 'Kurdish',
    lo: 'Lao',
    la: 'Latin',
    lv: 'Latvian',
    li: 'Limburgan',
    ln: 'Lingala',
    lt: 'Lithuanian',
    lu: 'Luba-Katanga',
    lb: 'Luxembourgish',
    mk: 'Macedonian',
    mg: 'Malagasy',
    ms: 'Malay',
    ml: 'Malayalam',
    mt: 'Maltese',
    gv: 'Manx',
    mi: 'Maori',
    mr: 'Marathi',
    mh: 'Marshallese',
    mn: 'Mongolian',
    na: 'Nauru',
    nv: 'Navajo',
    nd: 'North Ndebele',
    nr: 'South Ndebele',
    ng: 'Ndonga',
    ne: 'Nepali',
    no: 'Norwegian',
    nb: 'Norwegian Bokmål',
    nn: 'Norwegian Nynorsk',
    oc: 'Occitan',
    oj: 'Ojibwa',
    or: 'Oriya',
    om: 'Oromo',
    os: 'Ossetian',
    pi: 'Pali',
    ps: 'Pashto',
    fa: 'Persian',
    pl: 'Polish',
    pt: 'Portuguese',
    pa: 'Punjabi',
    qu: 'Quechua',
    ro: 'Romanian',
    rm: 'Romansh',
    rn: 'Rundi',
    ru: 'Russian',
    se: 'Northern Sami',
    sm: 'Samoan',
    sg: 'Sango',
    sa: 'Sanskrit',
    sc: 'Sardinian',
    sr: 'Serbian',
    sn: 'Shona',
    sd: 'Sindhi',
    si: 'Sinhala',
    sk: 'Slovak',
    sl: 'Slovenian',
    so: 'Somali',
    st: 'Southern Sotho',
    es: 'Spanish',
    su: 'Sundanese',
    sw: 'Swahili',
    ss: 'Swati',
    sv: 'Swedish',
    tl: 'Tagalog',
    ty: 'Tahitian',
    tg: 'Tajik',
    ta: 'Tamil',
    tt: 'Tatar',
    te: 'Telugu',
    th: 'Thai',
    bo: 'Tibetan',
    ti: 'Tigrinya',
    to: 'Tonga',
    ts: 'Tsonga',
    tn: 'Tswana',
    tr: 'Turkish',
    tk: 'Turkmen',
    tw: 'Twi',
    ug: 'Uighur',
    uk: 'Ukrainian',
    ur: 'Urdu',
    uz: 'Uzbek',
    ve: 'Venda',
    vi: 'Vietnamese',
    vo: 'Volapük',
    wa: 'Walloon',
    cy: 'Welsh',
    wo: 'Wolof',
    xh: 'Xhosa',
    ii: 'Sichuan Yi',
    yi: 'Yiddish',
    yo: 'Yoruba',
    za: 'Zhuang',
    zu: 'Zulu',

    // Some browsers might use `zz` to imply an unknown locale
    zz: 'Unknown',

    // Some browsers use one-long or three-long codes so we're adding here as fallback
    h: 'Croatian',
    chr: 'Cherokee',
    cmn: 'Chinese Mandarin',
    fil: 'Filipino',
    não: 'Norwegian',
    yue: 'Chinese Cantonese',
}

// This is only used as a fallback for some languages that don't usually
// come in the locale-country format (such as nl-NL usually being presented simply as nl)
// but that can't simply be translated to a flag by capitalizing the locale
const LANGUAGE_CODE_TO_EMOJI_FLAG_OVERRIDE: Record<string, string> = {
    ar: '🇪🇬', // Arabic -> Egypt, very very tricky, there's no good representation for the "default Arab country", the Egyptian variant is the most commonly understood
    af: '🇿🇦', // Afrikaans -> South Africa
    ta: '🇮🇳', // Tamil -> India
    eu: '🇪🇸', // Basque -> Spain, tricky, but there's no better flag than the Spanish one, we could move to custom SVGs if we wanted to solve this
    cy: '🏴󠁧󠁢󠁷󠁬󠁳󠁿', // Welsh -> Wales
    ne: '🇳🇵', // Nepali -> Nepal
    zz: '🇺🇳', // Unknown Language -> UN flag?
}
